package com.example.musicaiap.ui.home

import android.util.Log
import androidx.lifecycle.viewModelScope
import com.example.musicaiap.data.repository.FakeMusicRepository
import com.example.musicaiap.data.repository.LocalMusicScanner
import com.example.musicaiap.data.repository.MusicRepository
import com.example.musicaiap.data.repository.RoomMusicRepository
import com.example.musicaiap.domain.model.Playlist
import com.example.musicaiap.domain.model.Song
import com.example.musicaiap.mvi.base.MviViewModel
import com.example.musicaiap.service.MediaBrowserHelper
import com.example.musicaiap.service.PlaybackState
import com.example.musicaiap.ui.player.PlayerController
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
import androidx.media3.common.MediaItem
import androidx.media3.common.util.UnstableApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/**
 * 首页ViewModel
 * 负责处理首页的业务逻辑，包括加载内容、播放控制和本地音乐扫描
 * 实现MVI架构中的ViewModel层，处理Intent并更新State
 */
@HiltViewModel
@UnstableApi
class HomeViewModel @Inject constructor(
    private val musicRepository: MusicRepository,
    private val mediaBrowserHelper: MediaBrowserHelper,
    private val localMusicScanner: LocalMusicScanner,
    private val playerController: PlayerController
) : MviViewModel<HomeContract.State, HomeContract.Intent, HomeContract.Effect>() {
    
    // 暴露播放状态以供UI层访问
    val playbackState: StateFlow<PlaybackState> = mediaBrowserHelper.playbackState
    
    data class HomeState(
        val isLoading: Boolean = false,
        val error: String? = null,
        val playlists: List<Playlist> = emptyList(),
        val recommendSongs: List<Song> = emptyList(),
        val localSongs: List<Song> = emptyList(),
        val isLocalMusicSelected: Boolean = false,
        val isScanningLocalMusic: Boolean = false,
        val localMusicError: String? = null,
        val recentHistory: List<Song> = emptyList(),
        val currentPlaylist: List<Song> = emptyList()
    )
    
    /**
     * 创建初始状态
     * @return 空的初始状态
     */
    override fun createInitialState(): HomeContract.State = HomeContract.State()
    
    init {
        // 观察媒体播放器的播放状态，并更新UI状态
        mediaBrowserHelper.playbackState.onEach { playbackState ->
            when (playbackState) {
                is PlaybackState.Ready -> {
                    viewModelScope.launch {
                        val currentSong = withContext(Dispatchers.IO) {
                            playbackState.currentMediaItem?.let { mediaItem ->
                                musicRepository.getSongById(mediaItem.mediaId)
                            }
                        }

                        // 获取当前播放列表
                        // TODO: Refine playlist logic based on actual playback source (e.g., from PlayerController state)
                        // Temporarily assign localSongs if available, otherwise empty. This might not be correct in all cases.
                        val currentPlaylist = currentState.localSongs.takeIf { it.isNotEmpty() } ?: emptyList()
                        /* val currentPlaylist = if (currentState.isLocalMusicSelected && currentState.localSongs.isNotEmpty()) {
                            currentState.localSongs
                        } else {
                            emptyList()
                        } */ // Corrected the comment block to include the closing brace

                        setState {
                            copy(
                                currentPlayingSong = currentSong,
                                isPlayerVisible = playbackState.currentMediaItem != null,
                                isPlaying = playbackState.isPlaying,
                                currentPosition = playbackState.currentPosition,
                                duration = playbackState.duration,
                                currentPlaylist = currentPlaylist
                            )
                        }
                    }
                }
                is PlaybackState.Error -> {
                    // 处理错误状态，显示错误提示
                    println("HomeViewModel: 播放错误 - ${playbackState.message}")
                    sendEffect(HomeContract.Effect.ShowToast(playbackState.message))
                }
                else -> {
                    setState { 
                        copy(
                            isPlayerVisible = false,
                            currentPlaylist = emptyList()
                        )
                    }
                }
            }
        }.launchIn(viewModelScope)
        
        // 启动时检查本地音乐数据库
        checkLocalMusicDatabase()
        
        // 加载播放历史
        loadRecentHistory()
    }
    
    /**
     * 检查本地音乐数据库
     * 冷启动时检查数据库中是否有本地音乐
     */
    private fun checkLocalMusicDatabase() {
        viewModelScope.launch {
            try {
                // 从数据库中查询本地音乐数量
                if (musicRepository is RoomMusicRepository) {
                    val localSongsCount = (musicRepository as RoomMusicRepository).countLocalSongs()
                    println("数据库中发现 $localSongsCount 首本地音乐")
                    
                    if (localSongsCount > 0) {
                        // 数据库中有本地音乐，加载它们
                        val localSongs = (musicRepository as RoomMusicRepository).getLocalSongs()
                        setState { copy(localSongs = localSongs) }
                        println("从数据库加载了 ${localSongs.size} 首本地音乐")
                    }
                }
            } catch (e: Exception) {
                println("检查本地音乐数据库出错: ${e.message}")
                e.printStackTrace()
            }
        }
    }
    
    /**
     * 加载最近的播放历史
     */
    private fun loadRecentHistory() {
        viewModelScope.launch {
            try {
                if (musicRepository is RoomMusicRepository) {
                    val history = (musicRepository as RoomMusicRepository).getRecentHistory()
                    setState { copy(recentHistory = history) }
                }
            } catch (e: Exception) {
                println("加载播放历史失败: ${e.message}")
            }
        }
    }
    
    /**
     * 处理用户意图
     * 根据不同的意图类型执行相应的操作
     *
     * @param intent 用户意图
     */
    override fun handleIntent(intent: HomeContract.Intent) {
        when (intent) {
            is HomeContract.Intent.LoadContent -> loadInitialData() // Renamed and repurposed loadContent
            is HomeContract.Intent.ClickSong -> playSong(intent.song)      // 点击歌曲
            // Removed: ClickPlaylist case
            is HomeContract.Intent.TogglePlayPause -> mediaBrowserHelper.togglePlayPause()  // 切换播放/暂停
            is HomeContract.Intent.NextSong -> mediaBrowserHelper.skipToNext()  // 下一首
            is HomeContract.Intent.PreviousSong -> mediaBrowserHelper.skipToPrevious()  // 上一首
            is HomeContract.Intent.SeekTo -> mediaBrowserHelper.seekTo(intent.position)  // 调整播放位置
            is HomeContract.Intent.ClickMiniPlayer -> sendEffect(HomeContract.Effect.NavigateToPlayer)  // 点击迷你播放器
            is HomeContract.Intent.ScanLocalMusic -> scanLocalMusic()     // 扫描本地音乐
            // Removed: SelectLocalMusicTab case
            // Removed: SelectHomeTab case
            is HomeContract.Intent.PermissionResult -> handlePermissionResult(intent.granted)  // 处理权限结果
        }
    }

    /**
     * 加载初始数据（本地歌曲和播放历史）
     * 这个方法现在主要用于刷新或确保数据已加载，因为 init 块已经调用了它们。
     */
    private fun loadInitialData() {
        // No need to set loading state as these fields are not directly tied to a loading indicator anymore
        checkLocalMusicDatabase()
        loadRecentHistory()
    }
    
    /**
     * 播放歌曲
     * 调用mediaBrowserHelper播放指定的歌曲，并添加错误处理
     * 在本地音乐标签页时，将整个本地音乐列表设置为播放列表
     *
     * @param song 要播放的歌曲
     */
    private fun playSong(song: Song) {
        println("HomeViewModel: 尝试播放歌曲: ${song.title}, 来源: ${if (song.url.startsWith("content://")) "媒体库" else "本地文件"}")
        
        try {
            // 检查mediaBrowserHelper是否已连接
            if (mediaBrowserHelper.isConnected.value) {
                // TODO: Determine playback context (e.g., from LibraryScreen click) instead of isLocalMusicSelected
                // Assume playing from local list if localSongs is not empty and the song exists there.
                val songIndexInLocal = currentState.localSongs.indexOfFirst { it.id == song.id }
                if (currentState.localSongs.isNotEmpty() && songIndexInLocal != -1) {
                    // 在本地音乐列表中查找当前歌曲的索引 (already found)
                    val songIndex = songIndexInLocal
                    
                    // 如果找到了，则使用本地音乐列表作为播放列表
                    if (songIndex != -1) {
                        println("HomeViewModel: 使用本地音乐列表作为播放列表，从索引 $songIndex 开始播放")
                        // 调用playerController播放本地音乐列表
                        playerController.play(currentState.localSongs, songIndex, "LOCAL")
                        
                        // 更新当前播放列表状态
                        setState { copy(currentPlaylist = currentState.localSongs) }
                    } else {
                        // 未找到，则直接播放单首歌曲
                        println("HomeViewModel: 在本地音乐列表中未找到歌曲，直接播放单曲")
                        playerController.play(song, "SINGLE")
                        
                        // 更新当前播放列表状态为空
                        setState { copy(currentPlaylist = emptyList()) }
                    }
                } else {
                    // 不是本地音乐标签或本地音乐列表为空，直接播放单首歌曲
                    playerController.play(song, "SINGLE")
                    
                    // 更新当前播放列表状态为空
                    setState { copy(currentPlaylist = emptyList()) }
                }
            } else {
                println("HomeViewModel: mediaBrowserHelper未连接，尝试连接")
                // 尝试连接mediaBrowserHelper
                mediaBrowserHelper.connect()
                // 添加短暂延迟后再次尝试
                viewModelScope.launch {
                    kotlinx.coroutines.delay(500)
                    if (mediaBrowserHelper.isConnected.value) {
                        println("HomeViewModel: 连接成功，开始播放")

                        // TODO: Determine playback context (e.g., from LibraryScreen click) instead of isLocalMusicSelected
                        // Assume playing from local list if localSongs is not empty and the song exists there.
                        val songIndexInLocalAfterConnect = currentState.localSongs.indexOfFirst { it.id == song.id }
                        if (currentState.localSongs.isNotEmpty() && songIndexInLocalAfterConnect != -1) {
                            // 在本地音乐列表中查找当前歌曲的索引 (already found)
                            val songIndex = songIndexInLocalAfterConnect
                            
                            // 如果找到了，则使用本地音乐列表作为播放列表
                            if (songIndex != -1) {
                                println("HomeViewModel: 连接后使用本地音乐列表播放，从索引 $songIndex 开始")
                                playerController.play(currentState.localSongs, songIndex, "LOCAL")
                                
                                // 更新当前播放列表状态
                                setState { copy(currentPlaylist = currentState.localSongs) }
                            } else {
                                // 未找到，则直接播放单首歌曲
                                playerController.play(song, "SINGLE")
                                
                                // 更新当前播放列表状态为空
                                setState { copy(currentPlaylist = emptyList()) }
                            }
                        } else {
                            // 不是本地音乐标签或列表为空，直接播放单首歌曲
                            playerController.play(song, "SINGLE")
                            
                            // 更新当前播放列表状态为空
                            setState { copy(currentPlaylist = emptyList()) }
                        }
                    } else {
                        println("HomeViewModel: 连接失败，无法播放")
                        sendEffect(HomeContract.Effect.ShowToast("无法连接到播放服务，请重试"))
                    }
                }
            }
        } catch (e: Exception) {
            println("HomeViewModel: 播放失败 - ${e.message}")
            e.printStackTrace()
            sendEffect(HomeContract.Effect.ShowToast("播放失败: ${e.message}"))
        }
    }
    
    /**
     * 导航到播放列表详情
     * 发送导航效应以打开播放列表详情页面
     *
     * @param playlist 要查看的播放列表
     */
    private fun navigateToPlaylist(playlist: Playlist) {
        sendEffect(HomeContract.Effect.NavigateToPlaylist(playlist.id))
    }
    
    /**
     * 扫描本地音乐
     * 当用户点击"扫描"按钮时执行，流程如下：
     * 1. 首先更新UI状态为"正在扫描"
     * 2. 请求存储权限（发送RequestStoragePermission效应）
     * 3. 权限回调会在handlePermissionResult中处理
     */
    private fun scanLocalMusic() {
        // 记录日志
        println("开始扫描本地音乐流程")
        
        // 标记为正在扫描，但不立即启动扫描
        setState { copy(isScanningLocalMusic = true, localMusicError = null) }
        
        // 请求权限
        sendEffect(HomeContract.Effect.RequestStoragePermission)
    }
    
    /**
     * 权限获取后执行实际扫描
     * 当存储权限被授予后调用，执行实际的音乐扫描操作
     */
    fun onPermissionGranted() {
        // 记录日志
        println("权限已获取，开始扫描")
        
        viewModelScope.launch {
            try {
                // 调用LocalMusicScanner扫描本地音乐
                // 这里已经在协程中，localMusicScanner.scanLocalMusic()内部会切换到IO线程
                val scannedSongs = localMusicScanner.scanLocalMusic()
                
                println("扫描完成，找到 ${scannedSongs.size} 首歌曲")
                
                // 过滤无效歌曲
                val validSongs = filterValidSongs(scannedSongs)
                
                println("过滤完成，有效歌曲 ${validSongs.size} 首，过滤掉 ${scannedSongs.size - validSongs.size} 首")
                
                // 保存扫描到的歌曲到仓库
                if (musicRepository is RoomMusicRepository) {
                    (musicRepository as RoomMusicRepository).saveLocalSongs(validSongs)
                    println("已将 ${validSongs.size} 首歌曲保存到数据库")
                } else if (musicRepository is FakeMusicRepository) {
                    (musicRepository as FakeMusicRepository).saveLocalSongs(validSongs)
                    println("已将 ${validSongs.size} 首歌曲保存到假数据仓库")
                }
                
                // 更新UI状态，显示扫描结果
                setState {
                    copy(
                        isScanningLocalMusic = false,
                        localSongs = validSongs
                    )
                }
                
                // 显示提示消息
                if (validSongs.isEmpty()) {
                    sendEffect(HomeContract.Effect.ShowToast("未找到有效音乐文件"))
                } else {
                    val filteredCount = scannedSongs.size - validSongs.size
                    if (filteredCount > 0) {
                        sendEffect(HomeContract.Effect.ShowToast("已找到 ${validSongs.size} 首有效音乐，过滤了 $filteredCount 首无效音乐"))
                    } else {
                        sendEffect(HomeContract.Effect.ShowToast("已找到 ${validSongs.size} 首音乐"))
                    }
                }
            } catch (e: Exception) {
                // 记录异常
                println("扫描失败: ${e.message}")
                e.printStackTrace()
                
                // 更新状态为扫描失败
            setState {
                copy(
                        isScanningLocalMusic = false,
                        localMusicError = e.message ?: "扫描本地音乐失败"
                    )
                }
                
                // 显示错误提示
                sendEffect(HomeContract.Effect.ShowToast(e.message ?: "扫描本地音乐失败"))
            }
        }
    }
    
    /**
     * 过滤有效的歌曲
     * 剔除无效或有问题的歌曲数据
     *
     * @param songs 原始扫描到的歌曲列表
     * @return 过滤后的有效歌曲列表
     */
    private fun filterValidSongs(songs: List<Song>): List<Song> {
        // 使用HashSet检测重复
        val uniqueTitles = HashSet<String>()
        
        return songs.filter { song ->
            val isValid = isValidSong(song)
            
            // 检查是否重复（标题+艺术家作为唯一性判断）
            val titleArtistKey = "${song.title}:${song.artist}".lowercase()
            val isUnique = uniqueTitles.add(titleArtistKey)
            
            // 记录过滤结果
            if (!isValid) {
                println("过滤无效歌曲: ${song.title} - ${song.artist}, 原因: 歌曲数据不完整或无效")
            } else if (!isUnique) {
                println("过滤重复歌曲: ${song.title} - ${song.artist}")
            }
            
            isValid && isUnique
        }
    }
    
    /**
     * 检查歌曲是否有效
     * 
     * @param song 要检查的歌曲
     * @return 如果歌曲数据有效则返回true，否则返回false
     */
    private fun isValidSong(song: Song): Boolean {
        // 1. 检查歌曲标题
        if (song.title.isBlank() || song.title == "未知标题") {
            return false
        }
        
        // 2. 检查艺术家
        if (song.artist.isBlank() || song.artist == "未知艺术家") {
            return false
        }
        
        // 3. 检查歌曲时长 (大于10秒，小于30分钟)
        if (song.duration < 10_000 || song.duration > 30 * 60 * 1000) {
            return false
        }
        
        // 4. 检查URL有效性
        if (song.url.isBlank() || !(song.url.startsWith("content://") || song.url.startsWith("file://"))) {
            return false
        }
        
        return true
    }

    // Removed: selectLocalMusicTab() function
    // Removed: selectHomeTab() function

    /**
     * 处理权限结果
     * 当权限请求结果返回时调用
     * 
     * @param granted 权限是否被授予
     */
    fun handlePermissionResult(granted: Boolean) {
        // 记录权限结果
        println("收到权限结果: granted=$granted, isScanningLocalMusic=${currentState.isScanningLocalMusic}")
        
        if (granted) {
            // 权限授予，不管标记状态如何，都执行扫描
            onPermissionGranted()
        } else {
            // 权限被拒绝，更新状态
            setState { 
                copy(
                    isScanningLocalMusic = false,
                    localMusicError = "无法获取存储权限，请在设置中开启权限"
                )
            }
            sendEffect(HomeContract.Effect.ShowToast("无法获取存储权限，请在设置中开启权限"))
        }
    }
} // Added missing closing brace for the class
